package sd.settemmezzo.register;

import java.io.IOException;
import java.net.BindException;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import org.apache.log4j.Logger;

import sd.settemmezzo.common.PlayerInterface;
import sd.settemmezzo.common.Player;
import sd.settemmezzo.common.Registration;
import sd.settemmezzo.graphic.UI_Server;
import sd.settemmezzo.util.Ring;
import sd.settemmezzo.web.ClassFileServer;

public class RegistrationServer extends UnicastRemoteObject implements Registration {

	private static final long serialVersionUID = 2341399656274902868L;

	private static Logger log = Logger.getLogger("RegistartionServer");
	private static UI_Server ui;

	private Player newplayer;
	private Ring players;
	private String name = "//localhost:1099/Registration";

	public static final int MINPLAYERS = 3;
	public static final int MAXPLAYERS = 12;
	private int idCounter = 1;

	public RegistrationServer() throws RemoteException {
		super();
		players = new Ring();
		
		try { 
			new ClassFileServer(2001,"bin/"); 
		} catch (BindException b) {
			System.err.println("[Web Server] Già in esecuzione.");
		} catch (IOException e) {
			System.err.println("[Web Server] Start failed.");
			e.printStackTrace(); 
		}
		
	}

	public void setnameRegistry(String name) {
		this.name = name;
	}

	public int register(PlayerInterface playerInterface, String name) throws RemoteException {
		
		/* Check if name is available */
		for (Player playerList : players) {
			if (playerList.getNamePlayer().equals(name)) {
				return -1;
			}
		}

		newplayer = new Player();

		newplayer.setId(idCounter);
		newplayer.setNamePlayer(name);
		newplayer.setPlayerInterface(playerInterface);
		players.add(newplayer);
		ui.setLogText("Registred Player: name='" + newplayer.getNamePlayer()
				+ "' id: '" + newplayer.getId() + "'");
		log.info("Registred Player: name='" + newplayer.getNamePlayer()
				+ "' id: '" + newplayer.getId() + "'");

		/* Starts the game */
		if (players.size() >= MINPLAYERS) {

			try {
				Thread.sleep(1); // Timeout prima dell'inizio del gioco

				ui.setLogText("Share List");
				new Thread() {
					public void run() {
						Thread.currentThread().setName("Invio Lista");
						for (Player p : players) {
							try {
								p.getPlayerInterface().setPlayersList(players);
							} catch (RemoteException e) {
								ui.setLogText("Node: " + p.getNamePlayer() + "is crashed");
								log.error("Node: " + p.getNamePlayer() + "is crashed" + e.getMessage());
								e.printStackTrace();
							}
							ui.setLogText("Send Ring to node " + p.getNamePlayer());
							log.info("Send Ring to node " + p.getNamePlayer());
						}
						
						// Nuova Lista Player
						players = new Ring();
						idCounter = 1;
						ui.setLogText("Raggiunto il numero minimo di giocatori,\nil server è disponibile per un nuovo giro");
					}
				}.start();
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}

		idCounter++;
		return newplayer.getId();
	}

	public boolean unregister(String name) throws RemoteException {
		for (Player playerList : players) {
			if (playerList.getNamePlayer().equals(name)) {
				players.remove(playerList);
				ui.setLogText("node: " + name + "unregister");
				log.info("Unregister Player: ." + playerList.getNamePlayer()
						+ " avvenuta con successo");
				return true;
			}
		}
		return false;
	}

	public void start() {
		//Registration registration;

		try {
			//registration = new RegistrationServer();
			Naming.rebind(name, this);
			ui.setLogText("[RegistrationServer] Bound.");
			log.info("[RegistrationServer] Bound.");
		} catch (RemoteException e) {
			log.error("RegistrationServer exception: " + e.getMessage());
			e.printStackTrace();
		} catch (MalformedURLException e) {
			log.error("RegistrationServer exception: " + e.getMessage());
			e.printStackTrace();
		}
	}

	public void stop() {
		try {
			Naming.unbind(name);
			log.info("Server interrotto dall'utente");
			ui.setLogText("[RegistrationServer] Unound.");
		} catch (Exception e) {
			log.error("Server in crash durante l'interruzione manuale");
			e.printStackTrace();
		}

	}

	public static void main(String[] args) {
		if (System.getSecurityManager() == null) {
			System.setSecurityManager(new RMISecurityManager());
		}
		
		log.info("Avvio Server");

		ui = new UI_Server();
		ui.setVisible(true);
		ui.initComponents();
		log.info("Avvio Grafica Completato");

	}

}